/**
利用了chan的指针类型，引用类型
channel的select的多个chan的非阻塞模式
selet在没有监听到chan的状态时，也是一种阻塞模式
 */
package scheduler

import (
	"imooc.com/crawler/engine"
)

type QueuedScheduler struct {
	requestChan chan engine.Request
	workerChan chan  chan engine.Request
}

func (q *QueuedScheduler) WorkerChan() chan engine.Request{
	return make(chan engine.Request)
}

func (q *QueuedScheduler) Submit(r engine.Request) {
	q.requestChan <- r
}

func (q *QueuedScheduler) WorkerReady(w chan engine.Request)  {
	q.workerChan <- w
}

func (q *QueuedScheduler) Run()  {
	q.workerChan = make(chan chan engine.Request)
	q.requestChan = make(chan engine.Request)
	//为了不阻塞，开启一个goroutine
	go func() {
		var requestQ []engine.Request
		var workerQ []chan engine.Request

		for  {
			var activeRequest engine.Request
			var activeWorker chan engine.Request
			if len(requestQ) > 0 && len(workerQ) > 0 {
				activeRequest = requestQ[0]
				activeWorker = workerQ[0]
			}
			//监听等待case中的变化
			select {
			case r := <- q.requestChan:
				requestQ = append(requestQ, r)
			case w := <- q.workerChan:
				workerQ = append(workerQ, w)
			case activeWorker <- activeRequest: //这一块就是给createWorker的in赋值,因为channel是指针类型,引用类型
				requestQ = requestQ[1:]
				workerQ = workerQ[1:]
			}
		}
	}()
}


